﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace System.Linq
{
	/// <summary>The LinqToCSV class</summary>
	/// <created author="laurentiu.macovei" date="Fri, 28 Jan 2011 15:17:03 GMT"/>
	public static class LinqToCSV
	{
		/// <summary>Serializes the given IEnumerable elements to Comma Separated Value (CSV)</summary>
		/// <param name="items"></param>
		/// <param name="includeHeader">Specify true to render the headers as well</param>
		/// <created author="laurentiu.macovei" date="Fri, 28 Jan 2011 15:17:04 GMT"/>
		public static string ToCsv<T>(this IEnumerable<T> items, bool includeHeader = false)
			where T : class
		{
			var csvBuilder = new StringBuilder();
			var properties = typeof(T).GetProperties();
			if (includeHeader)
			{
				string line = string.Join(",", properties.Select(p => p.Name.ToCsvValue()).ToArray());
				csvBuilder.AppendLine(line);
			}
			foreach (T item in items)
			{
				string line = string.Join(",", properties.Select(p => p.GetValue(item, null).ToCsvValue()).ToArray());
				csvBuilder.AppendLine(line);
			}
			return csvBuilder.ToString();
		}

		/// <summary>Converts the given value to CSV</summary>
		/// <param name="item"></param>
		/// <returns></returns>
		/// <created author="laurentiu.macovei" date="Fri, 28 Jan 2011 15:17:04 GMT"/>
		private static string ToCsvValue<T>(this T item)
		{
			if (item == null) return "\"\"";

			if (item is string)
			{
				return string.Format("\"{0}\"", item.ToString().Replace("\"", "\\\""));
			}
			double dummy;
			if (double.TryParse(item.ToString(), out dummy))
			{
				return string.Format("{0}", item);
			}
			return string.Format("\"{0}\"", item);
		}
	}
}
